﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;


using SpiritEngine.Source.ApplicationLayer;


namespace SpiritEngine.Source
{
    #region Globals

    #endregion


    /// <summary>
    /// This class is used to create an instance of the Spirit Engine.
    /// </summary>
    public static class Engine
    {
        #region Constants/Enums

        #endregion


        #region Structs

        #endregion


        #region Static Member Variables and Methods

        /// <summary>
        /// This function creats a SpiritEngine instance.
        /// </summary>
        /// <returns>The created EngineBase object (which contains the game engine instance and all of its components).</returns>
        public static ISE_EngineBase CreateSpiritEngine()
        {
            return CreateSpiritEngine(null);
        }

        /// <summary>
        ///  This overload allows you to pass in the command line arguments for the Engine to process.
        /// </summary>
        /// <param name="commandLineArgs">A string array containing the command line arguments that the application was started with.</param>
        /// <returns>The created EngineBase object (which contains the game engine instance and all of its components).</returns>
        public static ISE_EngineBase CreateSpiritEngine(string[] commandLineArgs)
        {
            EngineBase eb = null;


            // ==============================================================================================================================================
            // As you can see below, we are using conditional compilation so that the code can be easily compiled for different operating
            // systems.  The constants used here are defined in the properties for this project.  For example,
            // the OS_Windows preprocessor constant is only defined if we are using the Debug_Win or Release_Win build configurations.
            // To see this, open the project properties and make sure the Build tab is selected.  At the top is a text box labeled
            // "Conditional compilation symbols:".  You can edit settings for different build configurations by using the Configuration drop-down list
            // in the upper-left corner of this screen.  In the "Conditional compilation symbols:" text box, you will see the following text
            // if Debug_Windows or Release_Windows is the currently active build configuration:
            // "OS_WINDOWS"
            // This is how you define custom conditional compilation constants.  You can create multiple ones as well.  Just separate them with semicolons,
            // like this:
            // "OS_WINDOWS;SOME_OTHER_CONSTANT;ANOTHER_CONSTANT"
            //
            // We could also possibly create other constants later for different processor types if it should become necessary.
            // For example: CPU_X86 and CPU_X64
            //
            // ----------------------------------------------------------------------------------------------------------------------------------------------
            // IMPORTANT NOTE: Game projects built on top of the SpiritEngine will need to create the same build configurations used in this
            //                 project so they define the appropriate conditional compilation constants for each configuration.
            // ----------------------------------------------------------------------------------------------------------------------------------------------
            //
            // NOTE: The constant OS_ANOTHEROS is not defined anywhere.  It is just a dummy value to allow me to have a correct and
            // complete #if block setup even though currently we only support one OS.
            //
            // The #else clause at the end is for if someone tries to compile for an unsupported OS (in other words, if none of the
            // known OS constants are defined by the current build configuration, then the #else clause will compile in the line "#error Unsupported OS!"
            // which will display that text as a compiler error).
            // ==============================================================================================================================================


            // Check the OS.
#if OS_WINDOWS

            if (commandLineArgs != null)
                eb = new EngineBase(commandLineArgs);
            else
                eb = new EngineBase();


#elif OS_ANOTHEROS

            // Intialization code for this OS.

#elif OS_ANOTHEROS

            // Initialization code for this OS.
#else
#error Unsupported OS!
#endif



            return eb;
        }

        #endregion


        #region Member Variables

        #endregion


        #region Events/Delegates

        #endregion


        #region Constructors and Destructors (aka Finalizers)

        #endregion


        #region Non-Public Methods

        // This section is for methods that are declared as private, protected, protected internal, or internal.

        #endregion


        #region Public Methods

        #endregion


        #region Interface Methods

        // This section is for methods that are part of the interfaces that the class implements.

        #endregion


        #region Event Invocation Methods

        // This section is for methods that invoke the events of this class.  For example:
        //
        // Invoke the Changed event; called whenever list changes
        // protected virtual void OnChanged(EventArgs e) 
        // {
        //		if (Changed != null)
        //			Changed(this, e);
        // }

        #endregion


        #region Operators

        #endregion


        #region Debug Methods

        // This will compile the debug code only if the DEBUG symbol is defined.
        // To define this symbol for all source files in the project, open the Project Properties,
        // and go to the Build tab.  Check the "Define DEBUG constant" checkbox.  With this box checked,
        // the compiler will automatically define the symbol DEBUG.
#if (DEBUG)
        // put all debug methods in here...
#endif

        #endregion


        #region Properties

        #endregion

    }
}
